package com.common.app.utls

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.util.DisplayMetrics
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import com.common.app.data.bean.BaseCityModel
import com.common.app.data.bean.CommonMessageRelayModel
import com.common.base.app.extras.*
import com.common.base.utils.JsonUtils
import com.google.gson.reflect.TypeToken
import org.json.JSONArray
import org.json.JSONException
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.text.NumberFormat
import java.text.SimpleDateFormat
import java.util.*
import kotlin.text.isEmpty


/**
 * 作者：sosou
 * <p>
 * 版本：1.0
 * <p>
 * 创建日期：2022/8/20
 * <p>
 * 描述：
 * <p>
 * 修订历史：
 */
object Utils {
    //随机游客ID
    var visitorNumber: String = ""

    val mAllProvince: MutableList<BaseCityModel> = ArrayList<BaseCityModel>()
    private val mHotCities: MutableList<BaseCityModel> = ArrayList<BaseCityModel>()
    private val mAllCities: MutableList<BaseCityModel> = ArrayList<BaseCityModel>()

    fun hideKeyboard(context: Context) {
        val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }


    /**
     * 根据传入控件的坐标和用户的焦点坐标，判断是否隐藏键盘，如果点击的位置在控件内，则不隐藏键盘
     *
     * @param view
     * 控件view
     * @param event
     * 焦点位置
     * @return 是否隐藏
     */
    fun hideKeyboard(
        event: MotionEvent, view: View?,
        activity: Activity
    ) {
        try {
            if (view != null && view is EditText) {
                val location = intArrayOf(0, 0)
                view.getLocationInWindow(location)
                val left = location[0]
                val top = location[1]
                val right = (left
                        + view.getWidth())
                val bootom = top + view.getHeight()
                // 判断焦点位置坐标是否在空间内，如果位置在控件外，则隐藏键盘
                if (event.rawX < left || event.rawX > right || event.y < top || event.rawY > bootom) {
                    // 隐藏键盘
                    val token = view.getWindowToken()
                    val inputMethodManager = activity
                        .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    inputMethodManager.hideSoftInputFromWindow(
                        token,
                        InputMethodManager.HIDE_NOT_ALWAYS
                    )
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun longToTime(time: Long, format: String = "MM-dd HH:mm"): String {
        return SimpleDateFormat(format, Locale.getDefault()).format(Date(time))
    }

    fun getFourNum(): String {
        visitorNumber.isNoEmpty().yes { return visitorNumber }
        val str = "0123456789"
        val sb = StringBuilder(4)
        for (i in 0..3) {
            val ch = str[Random().nextInt(str.length)]
            sb.append(ch)
        }
        visitorNumber = sb.toString()
        return visitorNumber
    }

    fun drawableToBitmap(drawable: Drawable?): Bitmap? {
        if (drawable == null) {
            return null
        }
        var bitmap: Bitmap? = null
        if (drawable is BitmapDrawable) {
            if (drawable.bitmap != null) {
                return drawable.bitmap
            }
        }
        bitmap = if (drawable.intrinsicWidth <= 0 || drawable.intrinsicHeight <= 0) {
            // Single color bitmap will be created of 1x1 pixel
            Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
        } else {
            Bitmap.createBitmap(
                drawable.intrinsicWidth,
                drawable.intrinsicHeight,
                Bitmap.Config.ARGB_8888
            )
        }
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, canvas.width, canvas.height)
        drawable.draw(canvas)
        return bitmap
    }

    fun getUUid(): String {
        return UUID.randomUUID().toString()
    }

    fun getTimestamp(): String {    // 北京时间戳
        val zone = TimeZone.getTimeZone("Asia/Shanghai")
        val cal: Calendar = Calendar.getInstance(zone)
        return cal.timeInMillis.toString()
    }

    //检查数据是否已经在列表中有了,firstCount只检查前面几个
    inline fun <reified T> checkHasData(mData: List<Any>?, firstCount: Int = 5): Boolean {
        synchronized(this) {
            mData?.forEachIndexed { index, data ->
                if (index <= firstCount && data is T) {
                    return true
                }
            }
            return false
        }
    }

    //将字符串转换成List
    fun getListString(strValue: String): ArrayList<String> {
        if (strValue.isNoEmpty()) {
            return JsonUtils.fromJson(strValue, object : TypeToken<ArrayList<String>>() {}.type)
        }
        return ArrayList()
    }

    fun getListLong(strValue: String): ArrayList<Long> {
        if (strValue.isNoEmpty()) {
            return JsonUtils.fromJson(strValue, object : TypeToken<ArrayList<Long>>() {}.type)
        }
        return ArrayList()
    }

    //大数字不使用科学计数方法显示
    fun bigDouble(d: Double): String {
        val nf = NumberFormat.getInstance()
        // 是否以逗号隔开, 默认true以逗号隔开,如[123,456,789.128]
        nf.isGroupingUsed = false
        // 结果未做任何处理
        return nf.format(d)
    }


    /**
     * 需要的长度
     *
     * @param length
     */
    fun getRadom(length: Int): String {

        //获取一个随机数
        val rand = Math.random()
        //将随机数转换为字符串
        val str = rand.toString().replace("0.", "")
        var newStr = ""
        if (str.isNotEmpty() && str.length > length) {
            //截取字符串
            newStr = str.substring(0, length)
        }
        return newStr
    }

    /**
     * 随机13位
     *
     * @param length
     */
    fun getRandomNumber13(): String {
        val randomNumber = (1000000000000L..9999999999999L).random()
        return String.format("%013d", randomNumber)
    }

    /**
     * list转jsonArray字符串
     *
     * @param list
     * @return
     */
    fun list2JsonArray(list: List<String?>?,spliceStr: String?=","): String {
        if (list.isNullOrEmpty()) {
            return ""
        }
        val sb = StringBuffer()
        val iterator: Iterator<*> = list.iterator()
        while (iterator.hasNext()) {
            val str = iterator.next() as String
            if (!str.isNullOrEmpty()) {
                if (iterator.hasNext()) {
                    sb.append("$str$spliceStr")
                } else {
                    sb.append(str)
                }
            }
        }
        return sb.toString()
    }

    /**
     * 字符串转List
     *
     * @param mStr
     * @return
     */
    fun String2List(mStr: String?,spliceStr: String=","): MutableList<String>{
        val imgsUrl : MutableList<String> = mutableListOf()

        if (mStr.isNullOrEmpty()) {
            return imgsUrl
        }

        if (spliceStr.isNullOrEmpty()) {
            return imgsUrl
        }

        imgsUrl.addAll(listOf(*mStr.split(spliceStr.toRegex()).dropLastWhile { it.isEmpty() }
            .toTypedArray()))
        return imgsUrl
    }

    fun <T> notEmpty(list: List<T>?): Boolean {
        return !isEmpty(list)
    }

    fun <T> isEmpty(list: List<T>?): Boolean {
        return if (list == null || list.size == 0) {
            true
        } else false
    }

    // 将px值转换为dip或dp值
    fun px2dip(context: Context, pxValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (pxValue / scale + 0.5f).toInt()
    }

    // 将dip或dp值转换为px值
    fun dip2px(context: Context, dipValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (dipValue * scale + 0.5f).toInt()
    }

    // 将px值转换为sp值
    fun px2sp(context: Context, pxValue: Float): Int {
        val fontScale = context.resources.displayMetrics.scaledDensity
        return (pxValue / fontScale + 0.5f).toInt()
    }

    // 将sp值转换为px值
    fun sp2px(context: Context, spValue: Float): Int {
        val fontScale = context.resources.displayMetrics.scaledDensity
        return (spValue * fontScale + 0.5f).toInt()
    }

    // 屏幕宽度（像素）
    fun getWindowWidth(context: Activity): Int {
        val metric = DisplayMetrics()
        context.windowManager.defaultDisplay.getMetrics(metric)
        return metric.widthPixels
    }

    // 屏幕高度（像素）
    fun getWindowHeight(context: Activity): Int {
        val metric = DisplayMetrics()
        context.windowManager.defaultDisplay.getMetrics(metric)
        return metric.heightPixels
    }

    fun getDisplayMetrics(): DisplayMetrics {
        return Resources.getSystem().displayMetrics
    }


    // 根据Unicode编码判断中文汉字和符号
    private fun isChinese(c: Char): Boolean {
        val ub = Character.UnicodeBlock.of(c)
        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
    }

    // 判断中文汉字和符号
    fun isChinese(strName: String): Boolean {
        val ch = strName.toCharArray()
        for (i in ch.indices) {
            val c = ch[i]
            if (isChinese(c)) {
                return true
            }
        }
        return false
    }

    //   获取热门国家列表
    fun getHotCountryList(context: Activity): List<BaseCityModel> {
        mHotCities.isEmpty().no {
            return mHotCities
        }.otherwise {
            val br: BufferedReader
            try {
                br = BufferedReader(InputStreamReader(context.resources.assets.open("hotCountryCode.json")))
                var line: String?
                val sb = StringBuilder()
                while (br.readLine().also { line = it } != null) sb.append(line)
                br.close()
                val ja = JSONArray(sb.toString())

                val sca: MutableList<BaseCityModel> = ArrayList()
                for (i in 0 until ja.length()) {
                    val jo = ja.getJSONObject(i)
                    val nameShort = jo.getString("locale")
                    val name = jo.getString("zh")
                    val code = jo.getString("code")
                    val en = jo.getString("en")
                    val countrySortModel = BaseCityModel(name, nameShort, en, code,code)
                    sca.add(countrySortModel)
                }
                mHotCities.clear()
                mHotCities.addAll(sca)
            } catch (e: IOException) {
                e.printStackTrace()
            } catch (e: JSONException) {
                e.printStackTrace()
            }
        }

        return mHotCities
    }

    //   获取国家列表
    fun getCountryList(context: Activity): List<BaseCityModel> {
        mAllCities.isEmpty().no {
            return mAllCities
        }.otherwise {
            val br: BufferedReader
            try {
                br = BufferedReader(InputStreamReader(context.resources.assets.open("defaultCountryCode.json")))
                var line: String?
                val sb = StringBuilder()
                while (br.readLine().also { line = it } != null) sb.append(line)
                br.close()
                val ja = JSONArray(sb.toString())

                val sca: MutableList<BaseCityModel> = ArrayList()
                for (i in 0 until ja.length()) {
                    val jo = ja.getJSONObject(i)
                    val nameShort = jo.getString("locale")
                    val name = jo.getString("zh")
                    val code = jo.getString("code")
                    val en = jo.getString("en")
                    val countrySortModel = BaseCityModel(name, nameShort, en, code,code)
                    sca.add(countrySortModel)
                }
                mAllCities.clear()

                //对集合排序
                sca.sortWith { o1, o2 -> //根据拼音进行排序
                    o1.pinyin.compareTo(o2.pinyin)
                }
                mAllCities.addAll(sca)
            } catch (e: IOException) {
                e.printStackTrace()
            } catch (e: JSONException) {
                e.printStackTrace()
            }
        }

        return mAllCities
    }


    // 获取城市列表
    fun getCityList(): List<BaseCityModel> {
        mAllCities.isEmpty().no {
            return mAllCities
        }.otherwise {
            val br: BufferedReader
            try {
                br =
                    BufferedReader(InputStreamReader(getContext().resources.assets.open("allCity2.json")))
                var line: String?
                val sb = StringBuilder()
                while (br.readLine().also { line = it } != null) sb.append(line)
                br.close()
                val ja = JSONArray(sb.toString())
                val sca: MutableList<BaseCityModel> = ArrayList()
                for (i in 0 until ja.length()) {
                    val jo = ja.getJSONObject(i)
                    val name = jo.getString("name")
                    val code = jo.getString("code")
                    val pCode = jo.getString("pCode")
                    val en = jo.getString("pinyin")
                    val countrySortModel = BaseCityModel(name, name, en,pCode, code)
                    sca.add(countrySortModel)
                }
                mAllCities.clear()

                //对集合排序
                sca.sortWith { o1, o2 -> //根据拼音进行排序
                    o1.pinyin.compareTo(o2.pinyin)
                }
                mAllCities.addAll(sca)
            } catch (e: IOException) {
                e.printStackTrace()
            } catch (e: JSONException) {
                e.printStackTrace()
            }
        }

        return mAllCities
    }

    fun openBySystem(url: String?): Boolean {
        return try {
            val intent = Intent()
            intent.action = "android.intent.action.VIEW"
            intent.data = Uri.parse(url)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            getContext().startActivity(intent)
            true
        } catch (var3: java.lang.Exception) {
            false
        }
    }

    fun jumpToAppStore() {
        val packageName = getContext().packageName
        val uri = Uri.parse("market://details?id=$packageName")
        val intent = Intent("android.intent.action.VIEW", uri)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        getContext().startActivity(intent)
    }
}